﻿#if UNITY_EDITOR
using UnityEditor;
using UnityEngine;

namespace AI.Graph.Editor {


    [CustomEditor (typeof (AIBehaviour))]
    public class AIBehaviourInspector : UnityEditor.Editor {

        private SerializedProperty sharedController;
        private SerializedProperty parameterReferences;
        private SerializedProperty m_startOnAwake;


        private int selectedToolbarIndex;
        private int aiRuntimeModeIndex;

        private AIBehaviour behaviour;


        void OnEnable () {
            behaviour = target as AIBehaviour;

            sharedController = serializedObject.FindProperty ("m_sharedController");
            parameterReferences = serializedObject.FindProperty ("m_parameterReferences");
            m_startOnAwake = serializedObject.FindProperty ("m_startOnAwake");
        }


        public override void OnInspectorGUI () {
            EditorGUILayout.Space ();

            serializedObject.Update ();

//            if (Application.isPlaying) {
                DrawRuntimeElements ();
                EditorGUILayout.Space ();
//            }

            selectedToolbarIndex = GUILayout.Toolbar (selectedToolbarIndex, new[] {"General", "Exposed Parameter"});

            EditorGUILayout.Space ();

            switch (selectedToolbarIndex) {
                case 0:

                    EditorGUILayout.PropertyField (sharedController, new GUIContent ("Controller"));
                    EditorGUILayout.PropertyField (m_startOnAwake, new GUIContent ("Start On Awake"));

                    break;
                case 1:

                    DrawExposedParameterReferences ();

                    break;
            }

            serializedObject.ApplyModifiedProperties ();

            EditorGUILayout.Space ();
        }


        void DrawRuntimeElements () {
            GUI.enabled = Application.isPlaying;
            EditorGUILayout.BeginHorizontal ();

            GUILayout.FlexibleSpace ();

            if (behaviour.paused) {
                aiRuntimeModeIndex = 1;
            }
            else if (behaviour.started) {
                aiRuntimeModeIndex = 0;
            }
            else {
                aiRuntimeModeIndex = 2;
            }

            int newSelectedAiModeToolbarIndex = GUILayout.Toolbar (aiRuntimeModeIndex, new[] {new GUIContent (Styles.playButton), new GUIContent (Styles.pauseButton), new GUIContent (Styles.stopButton)}, GUILayout.Height (15), GUILayout.Width (3 * 30));

            if (newSelectedAiModeToolbarIndex != aiRuntimeModeIndex) {
                if (newSelectedAiModeToolbarIndex == 0) {
                    behaviour.StartAI ();
                }
                else if (newSelectedAiModeToolbarIndex == 1) {
                    behaviour.PauseAI ();
                }
                else if (newSelectedAiModeToolbarIndex == 2) {
                    behaviour.StopAI ();
                }

                aiRuntimeModeIndex = newSelectedAiModeToolbarIndex;
            }

            GUILayout.FlexibleSpace ();

            EditorGUILayout.EndHorizontal ();
            GUI.enabled = true;
        }


        void DrawExposedParameterReferences () {
            if (sharedController.objectReferenceValue != null) {
                AIController aiController = sharedController.objectReferenceValue as AIController;

                // add exposed parameters.
                for (int i = 0; i < aiController.exposedParameters.Length; i++) {
                    ExposedParameter p = aiController.exposedParameters[i];

                    if (!behaviour.ContainsExposedParameter (p)) {
                        int lastIndex = parameterReferences.arraySize;
                        parameterReferences.InsertArrayElementAtIndex (lastIndex);
                        SerializedProperty exposedParameterReference = parameterReferences.GetArrayElementAtIndex (lastIndex);
                        exposedParameterReference.FindPropertyRelative ("exposedParameter").objectReferenceValue = p;
                    }
                }

                EditorGUILayout.BeginVertical ();

                // draw exposed parameters.
                for (int i = 0; i < parameterReferences.arraySize; i++) {
                    SerializedProperty exposedParameterReference = parameterReferences.GetArrayElementAtIndex (i);
                    SerializedProperty exposedParameter = exposedParameterReference.FindPropertyRelative ("exposedParameter");
                    SerializedProperty unityObjectReference = exposedParameterReference.FindPropertyRelative ("unityObjectReference");

                    ExposedParameter parameter = exposedParameter.objectReferenceValue as ExposedParameter;

                    EditorGUILayout.BeginHorizontal ();

                    if (parameter == null || !aiController.ContainsExposedParameter (parameter)) {
                        parameterReferences.DeleteArrayElementAtIndex (i);
                    }
                    else if (parameter.type != null) {
                        if (parameter.type == typeof (UnityEngine.Object) || parameter.type.IsSubclassOf (typeof (UnityEngine.Object))) {
                            unityObjectReference.objectReferenceValue = EditorGUILayout.ObjectField (parameter.name, unityObjectReference.objectReferenceValue, parameter.type, true);

                            if (unityObjectReference.objectReferenceValue != null) {
                                if (unityObjectReference.objectReferenceValue.GetType () != parameter.type && !unityObjectReference.objectReferenceValue.GetType ().IsSubclassOf (parameter.type)) {
                                    unityObjectReference.objectReferenceValue = null;
                                }
                            }
                        }
                        else {
                            Debug.Log ("Not an UnityEngine.Object");
                        }
                    }
                    else {
                        unityObjectReference.objectReferenceValue = null;
                    }

                    EditorGUILayout.EndHorizontal ();
                }

                EditorGUILayout.EndVertical ();
            }
        }


        static class Styles {

            public static readonly Texture2D playButton = EditorGUIUtility.LoadAsset<Texture2D> ("Textures/btn_play.png");
            public static readonly Texture2D pauseButton = EditorGUIUtility.LoadAsset<Texture2D> ("Textures/btn_pause.png");
            public static readonly Texture2D stopButton = EditorGUIUtility.LoadAsset<Texture2D> ("Textures/btn_stop.png");

        }

    }


}
#endif